#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/5/10 22:19
# @Author  : huidong.bai
# @File    : run.py
# @Software: PyCharm

import os
import sys
from threading import Thread

from PyQt5.QtWidgets import QWidget, QApplication, QTreeView
from PyQt5.QtGui import QPixmap, QTextCursor, QStandardItemModel, QStandardItem, QIcon
from PyQt5.QtCore import QTimer, QObject, pyqtSignal
from ui.SpeakerRuntimeInfo import Ui_Form
from SmokeOneDragon.lib.SwitchButton import SwitchButton
from lib.SerialReader import log_read

from lib import adb_utils

# 定义全局线程类
thread = None


# 自定义信号发射对象
class MySignals(QObject):
    # 设置一个信号源
    log_print = pyqtSignal(str)


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.setWindowTitle('冒烟一条龙')
        self.ui.timer = QTimer()
        self.times = 1

        # 将自定义信号绑定槽函数
        self.signal = MySignals()
        self.signal.log_print.connect(self.print_all_logs)

        self.ui.switchButton = SwitchButton(54, 27, color='green')
        self.ui.timer.timeout.connect(self.show_speaker_info)
        self.ui.timer.start(1000)
        self.ui.horizontalLayout_6.addWidget(self.ui.switchButton)

        # 设置QPlainTextEdit最多显示的行数，这里最多限制10000行
        self.ui.plainTextEdit.setMaximumBlockCount(10000)
        # 设置QPlainTextEdit为只读模式
        self.ui.plainTextEdit.setReadOnly(True)

        # 设置QPlainTextEdit的Qss样式
        self.ui.plainTextEdit.setStyleSheet('background: black; color: yellow;')

        # switchButton绑定信号槽函数
        self.ui.switchButton.signal.clicked.connect(self.get_device_log)

        # 清除QPlainTextEdit的内容
        self.ui.btn_clear_log.clicked.connect(self.refresh_log_edit)

        # 设置标准结构树结构
        self.model = QStandardItemModel()
        self.ui.treeView_allCases.setModel(self.model)

        # 设置树结构编辑框不可编辑
        self.ui.treeView_allCases.setEditTriggers(QTreeView.NoEditTriggers)

        # 设置树节点的头隐藏
        self.ui.treeView_allCases.setHeaderHidden(True)

        # 设置树结构槽函数
        self.model.itemChanged.connect(self.check_state_change)

        # 添加按钮槽函数
        self.ui.btn_add_case.clicked.connect(lambda: self.get_all_select_case(self.model.invisibleRootItem()))

        # 删除按钮槽函数
        self.ui.btn_delete_case.clicked.connect(lambda: self.delete_case(self.select_model.invisibleRootItem()))

        self.select_model = QStandardItemModel()
        self.ui.treeView_selectCases.setModel(self.select_model)

        self.ui.treeView_selectCases.setHeaderHidden(True)
        self.ui.treeView_selectCases.setEditTriggers(QTreeView.NoEditTriggers)

        # 查看日志按钮事件绑定
        self.ui.btn_logFiles.clicked.connect(self.open_log_file)

        self.music_icon = QIcon('./imgs/music.png')
        self.folder_icon = QIcon('./imgs/mac_folder.png')

        self.load_info()
        self.tree_view()

    # 加载图片
    def load_info(self):
        pix = QPixmap('./imgs/大雅.png')
        self.ui.SpeakerImage.setPixmap(pix)
        w = int(100 * pix.width() / pix.height())
        self.ui.SpeakerImage.setMaximumWidth(w)
        self.ui.SpeakerImage.setScaledContents(True)

    # 初始化上方的Speaker信息
    def show_speaker_info(self):
        self.ui.lbl_speaker_sn.setText(adb_utils.get_adb_sn())
        self.ui.lbl_speaker_run_environment.setText('线上环境')
        self.ui.lbl_run_time.setText(str(self.times))
        self.times += 1

    # 初始化树节点
    def tree_view(self):
        # 添加根节点1
        root = QStandardItem('全局Case')
        root.setCheckable(True)
        root.setIcon(self.folder_icon)
        self.model.appendRow(root)

        path = './audios'
        for i in os.listdir(path):
            tmp = QStandardItem(i)
            tmp.setCheckable(True)
            tmp.setIcon(self.folder_icon)
            root.appendRow(tmp)
            new_path = os.path.join(path, i)
            for j in os.listdir(new_path):
                if j.split('.')[1] == 'mp3':
                    tmp_1 = QStandardItem(j)
                    tmp_1.setCheckable(True)
                    tmp_1.setIcon(self.music_icon)
                    tmp.appendRow(tmp_1)

    # 树节点触发函数
    def check_state_change(self, item: QStandardItem):
        # 如果节点可选并且含有子节点
        # TODO 这里也有点问题，需要重新思考一下父节点的处理

        if item.isCheckable() and item.hasChildren():
            state = item.checkState()
            # 获取当前选择状态
            for i in range(0, item.rowCount()):
                child = item.child(i)
                child.setCheckState(state)

    # 获取所有所选树节点
    def get_checked(self, node: QStandardItem) -> list:
        """ 得到当前节点选中的所有分支， 返回一个 list """
        # 获取子节点个数
        count = node.rowCount()

        # 选择的Case列表
        select_case_list = []

        if count:
            for i in range(0, count):
                # 判断是否选中
                child = node.child(i)
                if child.checkState():
                    # 判断是否还有子分支
                    if child.hasChildren():
                        select_case_list.extend(self.get_checked(child))
                    else:
                        text = child.text()
                        select_case_list.append(text)
        return select_case_list

    def get_all_select_case(self, node: QStandardItem):
        # 清空列表
        while self.select_model.invisibleRootItem().rowCount():
            self.select_model.invisibleRootItem().removeRow(0)

        # 重新添加内容
        select_case = self.get_checked(node)
        print(select_case)
        for i in select_case:
            tmp = QStandardItem(i)
            tmp.setCheckable(True)
            tmp.setIcon(self.music_icon)
            self.select_model.appendRow(tmp)

    def delete_case(self, node: QStandardItem):
        select_case = []
        rowcount = node.rowCount()
        # 获取保留的Case
        for i in range(0, rowcount):
            if not node.child(i).checkState():
                select_case.append(node.child(i).text())

        print(select_case)

        # 清空列表
        while node.rowCount():
            node.removeRow(0)

        # 然后再添加之前的内容
        for case in select_case:
            tmp = QStandardItem(case)
            tmp.setCheckable(True)
            tmp.setIcon(self.music_icon)
            self.select_model.appendRow(tmp)

    # 实时打印日志追加
    def print_all_logs(self, line):
        # 追加文本
        self.ui.plainTextEdit.appendPlainText(line)
        # 获取光标位置
        cursor = self.ui.plainTextEdit.textCursor()
        # 设置光标位置为文本最后
        cursor.movePosition(QTextCursor.End)
        self.ui.plainTextEdit.setTextCursor(cursor)
        # 设置光标一直保持可见
        self.ui.plainTextEdit.ensureCursorVisible()

    # 打印日志触发器
    def get_device_log(self, status):
        global thread

        if status:
            thread = Thread(target=log_read, args=(self.signal, ))
            thread.start()
        else:
            if thread is None:
                return
            thread.open = False

    # 清除日志
    def refresh_log_edit(self):
        self.ui.plainTextEdit.setPlainText('')

    def open_log_file(self):
        path = '/Users/xmly/Desktop/MyReposity/py-qt5-project/SmokeOneDragon/logs'
        cmd = f'open {path}'
        os.popen(cmd)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())
